package com.wm.wmcrm.common.aspect;

import com.alibaba.fastjson2.JSON;
import com.wm.wmcrm.common.annotation.SystemLog;
import com.wm.wmcrm.common.result.CurrentUsername;
import com.wm.wmcrm.sys.entity.SysLog;
import com.wm.wmcrm.sys.entity.SysUser;
import com.wm.wmcrm.sys.filter.PropertyPreExcludeFilter;
import com.wm.wmcrm.sys.service.ISysLogService;
import io.swagger.util.Json;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Date;

@Component
@Aspect
public class SyslogAspect {
    public static final String[] EXCLUDE_PROPERTIES = {"password"};
    @Resource
    ISysLogService sysLogService;
    @Pointcut("@annotation(com.wm.wmcrm.common.annotation.SystemLog)")
    public void logPointcut(){}

    @Around("logPointcut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long start = System.currentTimeMillis();
        Object obj = point.proceed();
        Long time = System.currentTimeMillis() - start;
        saveSysLog(point,time);
        return obj;
    }

    /**
     * 保存日志相关的方法
     * 操作的用户
     * 具体的方法
     * 操作的方法名称
     * 参数列表
     * 执行的时长
     * 客户端的ip
     * 记录创建的时间
     * @param point
     * @return
     */
    public void saveSysLog(ProceedingJoinPoint point, Long time){
        SysLog sysLog = new SysLog();
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        SystemLog annotation = method.getAnnotation(SystemLog.class);
        if(annotation!=null){
            sysLog.setOperation(annotation.value());
        }
        //获取操作用户
        String currentUsername = CurrentUsername.getCurrentUsername();
        sysLog.setUsername(currentUsername);


        //获取方法
        String className = point.getTarget().getClass().getName();
        String methodName = method.getName();
        sysLog.setMethod(className+"."+methodName+"()");

        //获取参数
        Object[] args = point.getArgs();
        String strArgs = "";
        for (Object arg:args){
            String s = JSON.toJSONString(arg,excludePropertyPreFilter());
            strArgs += s;
        }
        sysLog.setParams(strArgs);

        //获取方法执行时间
        sysLog.setTime(time);

        //记录的创建时间
        sysLog.setCreateDate(LocalDateTime.now());

        //获取ip
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes attributes = (ServletRequestAttributes) requestAttributes;
        if(attributes != null){
            HttpServletRequest request = attributes.getRequest();
            String remoteAddr = request.getRemoteAddr();
            sysLog.setIp(remoteAddr);
        }




        sysLogService.save(sysLog);


    }
    /**
     * 忽略敏感属性
     */
    public PropertyPreExcludeFilter excludePropertyPreFilter()
    {
        return new PropertyPreExcludeFilter().addExcludes(EXCLUDE_PROPERTIES);
    }
}
